
import { GameDataManager } from "../Managers/GameDataManager";
import { GameDataKey } from "../Enums/GameDataKey";
import { DelayFramer } from "../Ticks/DelayFramer";
import { LanguageManager } from "../Managers/LanguageManager";
import { EventManager } from "../Managers/EventManager";
import { ModuleEvent } from "../Event/ModuleEvent";
import { ModuleManager } from "../Managers/ModuleManager";
import { Application } from "./Application";
import { UIEvent } from "../Event/UIEvent";
import { IModule } from "../Interfaces/IModule";
import { SceneEvent } from "../Event/SceneEvent";
import { ResouceManager } from "../Managers/ResouceManager";
import { Fun } from "../Utility/dx/Fun";

import { ModuleNames } from "../Enums/ModuleNames";
import { GameLayer } from "../Enums/GameLayer";
import { getTimer } from "../Utility/dx/getTimer";
import { FProxy } from "./FProxy";
import { Client } from "../Network/Socket/Client";
import { ClientManager } from "../Managers/ClientManager";
import { ClientName } from "../Enums/ClientName";
import { LoginHandler } from "../../NetWork/OtherNetwork/LoginHandler";
import { WriteCommand } from "../../NetWork/WriteCommand/WriteCommand";
import ConfirmModule from "../../../Modules/Common/ConfirmModule";
import MaskModule from "../../../Modules/Common/MaskModule";
import { CacheManager } from "../Managers/CacheManager";
import { StoreManager } from "../Managers/StoreManager";
import { SceneName } from "../Event/GameEvent";
import { WriteCmdEvent } from "../Event/WriteCmdEvent";

export class ApplicationMediator {
    public static ClassName: string = "ApplicationMediator";

    private hiddeStartTime: number = 0;
    private motionLastTime: number = 0;
    private acceleration = { x: 0, y: 0, z: 0 };


    private _proxy : FProxy
    private _client : Client
    private _lobbyMsg : LoginHandler

    private hiddeRefreshInterval: number = 1000 * 60 * 3;
    public initialize(): void {
        this.initDatas();
        this.addEvents();
        this.initModules();
        this.LoadingCache();
    }

    protected initDatas(): void {
        //let webData = {ApiUrl:"http://localhost:8080/web01_exec/web/"};
        //let webData = {ApiUrl:"http://windows.starnet99.local/ExternalGameAPI/"};
        //let webData = {ApiUrl:"http://192.168.0.224/ExternalGameAPI/"};
        let webData = { ApiUrl: "http://127.0.0.1:8001/GameLogin"};
        GameDataManager.instance.setDictData(GameDataKey.WEB_DATA, webData);
        DelayFramer.executeFrameDelay = 17;
        LanguageManager.ChangeLanguage(0);

        (<any>window).GameDataManger = GameDataManager
        
    }

    protected LoadingCache() : void {
        ResouceManager.LoadPrefab('GameCommon/Self_holds_Mahjongs', Fun(res => StoreManager.NewNode(CacheManager.GetCache(res)), this));
        ResouceManager.LoadPrefab('GameCommon/Flods_Out', Fun(res => StoreManager.NewNode(CacheManager.GetCache(res)), this));
    }

    protected initModules(): void {

        
        ModuleManager.instance.addModuleClass(ModuleNames.Confirm, ConfirmModule);
        ModuleManager.instance.addModuleClass(ModuleNames.Mask, MaskModule);

    }
    protected addEvents(): void {
        EventManager.addEvent(this, ModuleEvent.SHOW_MODULE, this.showModule);
        EventManager.addEvent(this, ModuleEvent.HIDE_MODULE, this.hideModule);
        EventManager.addEvent(this, ModuleEvent.DISPOSE_MODULE, this.disposeModule);
        EventManager.addEvent(this, ModuleEvent.PLAY_DISPOSE_ANIMATION, this.playDisposeModuleAnmiation);
        EventManager.addEvent(this, UIEvent.ADD_TO_LAYER, this.onAddToLayer);
        EventManager.addEvent(this, UIEvent.DISPOSE_LAYER_ELEMENTS, this.onDisposeLayerElements);
        EventManager.addEvent(this, UIEvent.HIDE_LAYER_ELEMENTS, this.onHideLayerElements);
        EventManager.addEvent(this, SceneEvent.CHANGE_SCENE, this.onChangeScene);



        
        // EventManager.addEvent(this,SceneEvent.SET_CURRENT_SCENE,this.onSetCurrentScene);
        // EventManager.addEvent(this,SceneEvent.DESTROY_CURRENT_SCENE,this.onDestroyCurrentScene);
        // document.onvisibilitychange = (evt) => this.onVisibilityChange();
        // if (window["DeviceMotionEvent"]) {
        //     window.addEventListener('devicemotion', (evt) => this.deviceMotionHandler(evt), false);
        // }
        // 
    }

    private deviceMotionHandler(evt): void {
        let curTime = getTimer();
        let diffTime = curTime - this.motionLastTime;
        if (diffTime > 120) {
            this.motionLastTime = curTime;
            var gravity = evt.accelerationIncludingGravity;
            let speed = Math.abs(gravity.x + gravity.y + gravity.z - this.acceleration.x - this.acceleration.y - this.acceleration.z) / diffTime * 1000;
            if (speed > 300) {
                alert("你摇动了手机");
                //navigator.vibrate([300,200,300,200,300]);
                navigator.vibrate([300, 200, 300, 200, 300, 200, 300, 200, 300, 200, 300]);
            }
            this.acceleration = gravity;
        }
    }

    // private onVisibilityChange(): void {
    //     //navigator.vibrate([300,200,300,200,300]);
    //     var isHidden = document.hidden;
    //     if (isHidden) {
    //         this.hiddeStartTime = getTimer();
    //     } else {
    //         if (getTimer() - this.hiddeStartTime >= this.hiddeRefreshInterval) {
    //             console.log("刷新当前网页");
    //             EventManager.dispatchEvent(new ModuleEvent(ModuleEvent.SHOW_MODULE, ModuleNames.Popup, null, GameLayer.Window, {
    //                 msg: "与服务器断开连接，请刷新重连...", type: PopupType.CONFIRM_WINDOW, onConfirm: function (): void {
    //                     window.location.reload();
    //                 }
    //             }));
    //             return;
    //         }
    //     }
    //     EventManager.dispatchEventWith(GameEvent.ON_APPLICATION_VISIBLE, isHidden);
    // }


    //获得场景
    private onChangeScene(evt: SceneEvent): void {
        let sceneName = evt.sceneName;
        //console.log(evt.data.test)
        ResouceManager.LoadScene(sceneName, Fun(this.onLoadSceneComplete, this, true, [evt.data]), Fun(this.onLoadSceneProgress, this, true, [sceneName]));
    }

    //加载进度
    protected onLoadSceneProgress(sceneName: string, test : string,progress: any): void {
        // console.log(test)
        EventManager.dispatchEvent(new SceneEvent(SceneEvent.LOAD_PROGRESS, sceneName, progress))
    }

    //加载完成
    private onLoadSceneComplete(data: any, sceneName: string): void {
        if(data&&data.CallFun)
            data.CallFun(data,sceneName)
        else
            cc.director.loadScene(sceneName, () => Application.CurrentScene.onGetSceneData(data));
    }

    private showModule(evt: ModuleEvent): void {
        if (evt.data != null && evt.data['hasPreload'] == true && !ModuleManager.instance.hasModule(evt.moduleName, evt.instanceName)) {
            EventManager.dispatchModuleEventWith(ModuleEvent.SHOW_MODULE, ModuleNames.Preload, GameLayer.Window);
            EventManager.addEvent(this, ModuleEvent.LOAD_MODULE_ASSET_COMPLETE + evt.moduleName, this.onModuleComplete);
        }



        let m: IModule = ModuleManager.instance.getModule(evt.moduleName, evt.instanceName);
        if (m == null) return;

        if (evt.moduleName == "ConfirmModule") {
            console.log("show了模块 -> ", evt.moduleName, cc.director.getScene().name)
        }

        m.moduleName = evt.moduleName;
        let layer = Application.CurrentScene.getLayer(evt.gameLayer);
        m.startModule();
        m.show(layer, evt.data);
    }
    private onModuleComplete(evt: ModuleEvent) {
        EventManager.dispatchModuleEventWith(ModuleEvent.HIDE_MODULE, ModuleNames.Preload);
        EventManager.removeEvent(this, ModuleEvent.LOAD_MODULE_ASSET_COMPLETE, this.onModuleComplete);
    }
    private hideModule(evt: ModuleEvent): void {
        if (!ModuleManager.instance.hasModule(evt.moduleName, evt.instanceName)) return;
        let m: IModule = ModuleManager.instance.getModule(evt.moduleName, evt.instanceName);
        m.hide();
    }
    private playDisposeModuleAnmiation(evt: ModuleEvent): void {
        if (!ModuleManager.instance.hasModule(evt.moduleName, evt.instanceName)) return;
        let m: IModule = ModuleManager.instance.getModule(evt.moduleName, evt.instanceName);
        m.isPlayDisposeAnimation = true;
        ModuleManager.instance.disposeModule(evt.moduleName, evt.instanceName);
        //ModuleManager.instance.disposeModule(evt.moduleName, evt.instanceName);
    }
    private disposeModule(evt: ModuleEvent): void {
        if (!ModuleManager.instance.hasModule(evt.moduleName, evt.instanceName)) return;
        ModuleManager.instance.disposeModule(evt.moduleName, evt.instanceName);
        console.log("模块被销毁 -> ", evt.moduleName)

    }
    private onAddToLayer(evt: UIEvent): void {
        let view = evt.view;
        if (view == null) return;
        let layer = Application.CurrentScene.getLayer(evt.gameLayer);
        layer.addChild(view);
        if (evt.data != null) {
            let n: cc.Node = view.node;
            if (n == null) n = view;
            if (evt.data["x"]) n.x = evt.data["x"];
            if (evt.data["y"]) n.y = evt.data["y"];
        }
    }
    private onDisposeLayerElements(evt: UIEvent): void {

    }
    private onHideLayerElements(evt: UIEvent): void {}
    

    public set Proxy(p:FProxy){
        if(this._proxy != null)return
        this._proxy = p;
        this._proxy.initialize()
    }

    public get Proxy () : FProxy{
        return this._proxy
    }

    public set ConnectService(c:any){
        if(this._client!=null){
            console.log("已经链接到服务器")
        }
        else{
            this._client = ClientManager.GetClientByName(ClientName.GAME_CLIENT)
            this._client.connectURL(c)
            this._client.addCallBacks(this, this.onConnect, this.onClientData, this.onClose, this.onError, this.onTimeOut)
        }
            
    } 

    public get ConnectService() : any{
        return this._client
    }

    private onConnect() : void {
        this._lobbyMsg = new LoginHandler
        //{"id":"login","data":{"safecode":342312}}
        new WriteCommand(WriteCmdEvent.CMD_LoginServer)
        // console.log("链接成功")
    }

    private onClientData() : void {}

    private onClose() : void {
        EventManager.dispatchModuleEventWith(ModuleEvent.SHOW_MODULE, ModuleNames.Mask, GameLayer.Window)
        EventManager.dispatchModuleEventWith(ModuleEvent.SHOW_MODULE, ModuleNames.Confirm, GameLayer.Window,{
            content:"网络错误,连接服务器失败",
            Confirm:()=>{
                this._client=null
                EventManager.dispatchModuleEventWith(ModuleEvent.DISPOSE_MODULE, ModuleNames.Mask)
                EventManager.dispatchModuleEventWith(ModuleEvent.DISPOSE_MODULE, ModuleNames.Confirm);
                EventManager.dispatchEvent(new SceneEvent(SceneEvent.CHANGE_SCENE, SceneName.LOGIN_SCENE,{}));
            }
        });
    }

    private onError() : void {
        EventManager.dispatchModuleEventWith(ModuleEvent.SHOW_MODULE, ModuleNames.Confirm, GameLayer.Window,{
            content:"与服务器的连接出现错误!",
            Confirm:()=>{
                this._client=null
                EventManager.dispatchModuleEventWith(ModuleEvent.DISPOSE_MODULE, ModuleNames.Confirm);
            }
        });
    }

    private onTimeOut() : void {
        
        console.log('scoket超时')
    }
}
